﻿using System;
using System.Collections.Generic;
using System.Linq;
using Best.SmartCms.Dao;
using Best.SmartCms.Domain;
using Best.SmartCms.Dto.Response;
using Best.SmartCms.Dto;
using Best.SmartCms.Dto.Common;
using Best.SmartCms.Service.BizException;
using Best.SmartCms.Service.Common;
using Best.SmartCms.Utility;

namespace Best.SmartCms.Service
{
    /// <summary>
    /// Category服务
    /// </summary>
    public class CategoryService : IService
    {
        private readonly CategoryDao _categoryDao;
        private readonly WorkContext _workContext;


        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="mySqlDbContext"></param>
        /// <param name="workContext"></param>
        public CategoryService(MySqlDbContext mySqlDbContext, WorkContext workContext)
        {
            _workContext = workContext;
            _categoryDao = new CategoryDao(mySqlDbContext);
        }

        

        /// <summary>
        /// 分页列表
        /// </summary>
        /// <returns></returns>
        public List<CategoryListDto> PageList()
        {
            var list = _categoryDao.List();
            var result = new List<CategoryListDto>();
            var parentList = list.Where(p => p.ParentId == 0).ToList();
            foreach (var item in parentList)
            {
                var note = new CategoryListDto
                {
                    Id = item.Id,
                    Name = item.Name,
                    ParentId = item.ParentId,
                    UpdatedTime = item.UpdatedTime,
                    UpdatorName = item.UpdatorName,
                    Children = new List<CategoryListDto>()
                };

                GetChildren(list, note);
                result.Add(note);
            }

            return result;
        }

        private void GetChildren(List<Category> list, CategoryListDto parentNode)
        {
            var children = list.Where(p => p.ParentId == parentNode.Id).OrderBy(p => p.OrderNo).ToList();
            if (children.Count < 1)
            {
                return;
            }

            foreach (var item in children)
            {
                var note = new CategoryListDto
                {
                    Id = item.Id,
                    Name = item.Name,
                    ParentId = item.ParentId,
                    UpdatedTime = item.UpdatedTime,
                    UpdatorName = item.UpdatorName,
                    Children = new List<CategoryListDto>()
                };

                GetChildren(list,note);
                parentNode.Children.Add(note);
            }
        }


        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="dto"></param>
        public void Create(CategoryEditDto dto)
        {
            var entity = TinyMapperExtensions.Map<CategoryEditDto, Category>(dto);
            entity.CreatedTime=DateTime.Now;
            entity.CreatorId = _workContext.UserId;
            entity.CreatorName = _workContext.UserName;
            entity.UpdatorId = _workContext.UserId;
            entity.UpdatorName = _workContext.UserName;
            entity.UpdatedTime = DateTime.Now;
            _categoryDao.Add(entity);
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="dto"></param>
        public void Edit(CategoryEditDto dto)
        {
            var entity = _categoryDao.GetSingle(dto.Id);
            if (entity == null)
            {
                throw new ParameterNullException($"未找到{dto.Id}的数据");
            }

            TinyMapperExtensions.Map(dto, entity);
            entity.UpdatorId = _workContext.UserId;
            entity.UpdatorName = _workContext.UserName;
            entity.UpdatedTime = DateTime.Now;

            _categoryDao.Update(entity);
        }

        /// <summary>
        /// 详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public CategoryEditDto Info(long id)
        {
            var entity = _categoryDao.GetSingle(id);
            return TinyMapperExtensions.Map<Category, CategoryEditDto>(entity);
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        public void Delete(long id)
        {
            var entity = _categoryDao.GetSingle(id);
            if (entity == null)
            {
                throw new ParameterNullException($"未找到{id}的数据");
            }

            var children = _categoryDao.ListByParentId(id);
            if (children != null)
            {
                throw new ParameterNullException($"存在子级节点不能删除");
            }

            _categoryDao.Delete(entity);
        }

        /// <summary>
        /// 选择框
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public List<SelectOptionDto> Option(long? id)
        {
            var list = _categoryDao.List();
            if (id != null)
            {
                list = list.Where(p => p.Id != id).ToList();
                var children = list.Where(p => p.ParentId == id).ToList();
                foreach (var item in children)
                {
                    RemoveChildren(list,item);
                    list.Remove(item);
                }
            }

            var result = new List<SelectOptionDto> {new SelectOptionDto {Label = "请选择", Value = "0"}};
            result.AddRange(list.Select(p => new SelectOptionDto { Label = p.Name, Value = p.Id.ToString() }).ToList());
            return result;
        }

        private void RemoveChildren(List<Category> list, Category parent)
        {
            var children = list.Where(p => p.ParentId == parent.Id).ToList();
            foreach (var item in children)
            {
                RemoveChildren(list, item);
                list.Remove(item);
            }
        }
    }
}
